package cn1shared.ui;

import com.codename1.ui.Display;

import java.io.IOException;
import java.io.InputStream;


public abstract class ProgressInputStream extends InputStream {

	private final InputStream in;
	private final long length;
	private long bytesRead = 0;
	private volatile int percent = 0;
	private final Runnable runnable;

	public ProgressInputStream(InputStream in, long length) {
		this.in = in;
		this.length = length;
		runnable = new Runnable() {
			@Override
			public void run() {
				update(percent);
			}
		};
	}

	@Override
	public int read() throws IOException {
		int b = in.read();
		updateProgress(1);
		return b;
	}

	@Override
	public int read(byte[] b) throws IOException {
		return updateProgress(in.read(b));
	}

	@Override
	public int read(byte[] b, int off, int len) throws IOException {
		return updateProgress(in.read(b, off, len));
	}

	@Override
	public long skip(long n) throws IOException {
		return in.skip(n);  // we don't use this
	}

	@Override
	public void mark(int readlimit) {
		in.mark(readlimit);
	}

	@Override
	public void reset() throws IOException {
		in.reset();
	}

	@Override
	public boolean markSupported() {
		return false;
	}

	private int updateProgress(int numBytesRead) {
		if (numBytesRead > 0) {
			this.bytesRead += numBytesRead;
			int newPercent = (int) (100.f * bytesRead / length);
			if( newPercent > percent ) {
				percent = newPercent;
				Display.getInstance().callSeriallyAndWait(runnable);
			}
		}
		return numBytesRead;
	}

	protected abstract void update(int percent);
}
